home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / file < prev    next >
Encoding:
Text File  |  1989-09-30  |  14.4 KB  |  537 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              file.c
  10.  */
  11.  
  12. #include        "tex.h"
  13. #include        "cmds.h"
  14. #include        "heap.h"
  15. #include        "char.h"
  16. #include        "eq.h"
  17. #include        "token.h"
  18. #include        "scan.h"
  19. #include        "tokenstack.h"
  20. #include        "str.h"
  21. #include        "fmt.h"
  22. #include        "io.h"
  23. #include        "print.h"
  24. #include        "error.h"
  25. #include        "file.h"
  26.  
  27. char    name_of_file[FILE_NAME_SIZE];
  28. int             name_length;
  29.  
  30. int             area_delimiter;
  31. int             ext_delimiter;
  32.  
  33. str             cur_area;
  34. str             cur_name;
  35. str             cur_ext;
  36.  
  37. bool    name_in_progress = FALSE;
  38. str             job_area;
  39. str             job_name;
  40. str             log_name;
  41. str             dvi_name;
  42.  
  43. alpha_file              read_file[16];
  44.  
  45. int             read_open[17]; 
  46.  
  47. str             str_dvi;
  48. str             str_log;
  49. str             str_tex;
  50. str             str_tfm;
  51. str             str_fmt;
  52. str             str_texput;
  53.  
  54. bool
  55. begin_name ()
  56. {
  57.         area_delimiter = 0;
  58.         ext_delimiter = 0;
  59. }
  60.  
  61. bool
  62. more_name (c)
  63.         ascii   c;
  64. {
  65.         if (c == ' ')
  66.                 return FALSE;
  67.         else {
  68.                 if (c == '/') {
  69.                         area_delimiter = pool_ptr;
  70.                         ext_delimiter = 0;
  71.                 } else if (c == '.' && ext_delimiter == 0)
  72.                         ext_delimiter = pool_ptr;
  73.                 str_room(1);
  74.                 append_char(c);
  75.                 return TRUE;
  76.         }
  77. }
  78.  
  79. end_name ()
  80. {
  81.         if (str_ptr + 3 > MAX_STRINGS)
  82.                 overflow("number of strings", MAX_STRINGS);
  83.         if (area_delimiter == 0)
  84.                 cur_area = null_str;
  85.         else {
  86.                 cur_area = str_ptr;
  87.                 incr(str_ptr);
  88.                 str_start[str_ptr] = area_delimiter + 1;
  89.         }
  90.         if (ext_delimiter == 0) {
  91.                 cur_ext = null_str;
  92.                 cur_name = make_string();
  93.         } else {
  94.                 cur_name = str_ptr;
  95.                 incr(str_ptr);
  96.                 str_start[str_ptr] = ext_delimiter;
  97.                 cur_ext = make_string();
  98.         }
  99. }
  100.  
  101. #define append_to_name(F) \
  102.         {c = F; name_of_file[k] = xchr[c]; incr(k);}
  103.  
  104. pack_file_name (n, a, e)
  105.         str             n;
  106.         str             a;
  107.         str             e;
  108. {
  109.         ascii   c;
  110.         int             j;
  111.         int             k;
  112.                 
  113.         if (length(a) + length(n) + length(e) >= FILE_NAME_SIZE)
  114.                 overflow("file name size", FILE_NAME_SIZE);
  115.         k = 0;
  116.         for (j = str_start[a]; j < str_start[a+1]; incr(j))
  117.                 append_to_name(str_pool[j]);
  118.         for (j = str_start[n]; j < str_start[n+1]; incr(j))
  119.                 append_to_name(str_pool[j]);
  120.         for (j = str_start[e]; j < str_start[e+1]; incr(j))
  121.                 append_to_name(str_pool[j]);
  122.         name_length = k;
  123.         name_of_file[k] = NUL;
  124. }
  125.  
  126. print_file_name (n, a, e)
  127.         str             n;
  128.         str             a;
  129.         str             e;
  130. {
  131.         print_str(a);
  132.         print_str(n);
  133.         print_str(e);
  134. }
  135.  
  136. pack_job_name (s)
  137. {
  138.         cur_area = job_area;
  139.         cur_name = job_name;
  140.         cur_ext = s;
  141.         pack_cur_name();
  142. }
  143.  
  144. str
  145. make_name_string ()
  146. {
  147.         int             k;
  148.  
  149.         str_room(name_length);
  150.         for (k = 0; k < name_length; incr(k))
  151.                 append_char(xord[name_of_file[k]]);
  152.         return (make_string());
  153. }
  154.  
  155. scan_file_name ()
  156. {
  157.         name_in_progress = TRUE;
  158.         get_nbx_token();
  159.         begin_name();
  160.         loop {
  161.                 if (cur_cmd > OTHER_CHAR || cur_chr > 127) {
  162.                         back_input();
  163.                         break;
  164.                 }
  165.                 if (!more_name(cur_chr)) break;
  166.                 get_x_token();
  167.         }
  168.         end_name();
  169.         name_in_progress = FALSE;
  170. }
  171.  
  172. prompt_file_name (s, e)
  173.         char*   s;
  174.         str             e;
  175. {
  176.         int             k;
  177.  
  178.         if (s[0] == 'i' && s[1] == 'n')
  179.                 print_nl("! I can't find file `");
  180.         else print_nl("! I can't write on file `");
  181.         print_file_name(cur_name, cur_area, cur_ext);
  182.         print("'.");
  183.         if (e == str_tex)
  184.                 show_context();
  185.         print_nl("Please type another ");
  186.         print(s);
  187.         if (interaction < SCROLL_MODE)
  188.                 fatal_error("*** (job aborted, file error in nonstop mode)");
  189.         clear_terminal();
  190.         prompt_input(": ");
  191.         begin_name();
  192.         k = first;
  193.         while (buffer[k] == ' ' && k < last)
  194.                 incr(k);
  195.         loop {
  196.                 if (k == last)
  197.                         break;
  198.                 if (! more_name(buffer[k]))
  199.                         break;
  200.                 incr(k);
  201.         }
  202.         end_name();
  203.         if (cur_ext == null_str)
  204.                 cur_ext = e;
  205.         pack_cur_name();
  206. }
  207.  
  208. start_input ()
  209. {
  210.         scan_file_name();
  211.         if (cur_ext == null_str)
  212.                 cur_ext = str_tex;
  213.         pack_cur_name();
  214.         loop {
  215.                 begin_file_reading();
  216.                 if (cur_file = a_open_in())
  217.                         break;
  218.                 end_file_reading();
  219.                 if (cur_ext == str_tex) {
  220.                         cur_ext = null_str;
  221.                         pack_cur_name();
  222.                         begin_file_reading();
  223.                         if (cur_file = a_open_in())
  224.                                 break;
  225.                         end_file_reading();
  226.                 }
  227.                 prompt_file_name("input file name", str_tex);
  228.         }
  229.         name = a_make_name_string(cur_file);
  230.         if (job_name == 0) {
  231.                 job_area = cur_area;
  232.                 job_name = cur_name;
  233.                 open_log_file();
  234.                 if (job_area != null_str)
  235.                         set_def_area();
  236.         }
  237.         if (term_offset + length(name) > MAX_PRINT_LINE - 2)
  238.                 print_ln();
  239.         else if (term_offset > 0 || file_offset > 0)
  240.                 print_char(' ');
  241.         print_char('(');
  242.         print_str(name);
  243.         update_terminal(); 
  244.         state = NEW_LINE;
  245.         input_ln(cur_file, FALSE);
  246.         firm_up_the_line();
  247.         if (end_line_char < 0 || end_line_char > 127)
  248.                 decr(limit);
  249.         else buffer[limit] = end_line_char;
  250.         first = limit + 1;
  251.         loc = start;
  252.         line = 1;
  253. }
  254.  
  255. open_log_file ()
  256. {
  257.         int             k;
  258.         int             l;
  259.         char    months[37]; 
  260.         int             old_setting;
  261.  
  262.         old_setting = selector;
  263.         if (job_name == 0) {
  264.                 job_area = null_str;
  265.                 job_name = str_texput;
  266.         }
  267.         pack_job_name(str_log);
  268.         while ((log_file = a_open_out()) == NULL)
  269.                 prompt_file_name("transcript file name", str_log);
  270.         log_name = a_make_name_string(log_file);
  271.         selector = LOG_ONLY;
  272.         fputs(banner, log_file);
  273.         if (format_ident == 0)
  274.                 print(" (no format preloaded)");
  275.         else print_str(format_ident);
  276.         print_char(' ');
  277.         print_int(day);
  278.         print_char(' ');
  279.         strcpy(months, "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC");
  280.         for (k = 3 * month - 3; k < 3 * month; incr(k))
  281.                 putc(months[k], log_file);
  282.         print_char(' ');
  283.         print_int(year);
  284.         print_char(' ');
  285.         print_two(time / 60);
  286.         print_char(':');
  287.         print_two(time % 60);
  288.         input_stack[input_ptr] = cur_input;
  289.         print_nl("**");
  290.         l = input_stack[0].limit_field;
  291.         if (buffer[l] == end_line_char) decr(l);
  292.         for (k = 1; k <= l; incr(k))
  293.                 print_char(buffer[k]);
  294.         print_ln();
  295.         selector = old_setting + 2; 
  296. }
  297.  
  298. bool 
  299. open_fmt_file ()
  300. {
  301.         int             j;
  302.         
  303.         j = loc;
  304.         if (buffer[loc] == '&') {
  305.                 incr(loc);
  306.                 j = loc;
  307.                 buffer[last] = ' ';
  308.                 while (buffer[j] != ' ') incr(j);
  309.                 pack_buffered_name(loc, j);
  310.                 if (fmt_file = w_open_in()) goto found;
  311.                 wake_up_terminal();
  312.                 puts("Sorry, I can't find that format, will try PLAIN.");
  313.                 update_terminal();
  314.         }
  315.         strcpy(name_of_file, TeX_format_default);
  316.         name_length = 9;
  317.         if ((fmt_file = w_open_in()) == NULL) {
  318.                 puts("I can't find the PLAIN format file!");
  319.                 return FALSE;
  320.         }
  321. found: 
  322.         loc = j;
  323.         return TRUE;
  324. }
  325.  
  326. pack_buffered_name (a, b)
  327.         int             a;
  328.         int             b;
  329. {
  330.         ascii   c;
  331.         int             j;
  332.         int             k;
  333.  
  334.         k = 0;
  335.         for (j = a; j < b; incr(j))
  336.                 append_to_name(buffer[j]);
  337.         append_to_name(xchr['.']);
  338.         append_to_name(xchr['f']);
  339.         append_to_name(xchr['m']);
  340.         append_to_name(xchr['t']);
  341.         append_to_name(NUL);
  342.         name_length = b - a + 4;
  343. }
  344.  
  345. /* 
  346.  * fixed arrays are used to hold the paths, to avoid any possible problems
  347.  * involving interaction of malloc and undump
  348.  */     
  349.  
  350. char*   cur_path;
  351.  
  352. char    input_path[MAX_PATH_CHARS] = default_input_path;
  353. char    font_path[MAX_PATH_CHARS] = default_font_path;
  354. char    format_path[MAX_PATH_CHARS] = default_format_path;
  355.  
  356. set_paths ()
  357. {
  358.     char*       env_path;
  359.     char*       getenv();
  360.  
  361. /*ACORN This was tried in the first version.   I have since
  362.         decided to leave it as it originally was.
  363.  
  364.     if (env_path = getenv("CTEXINPUTS$PATH"))
  365.                 copy_path(input_path, env_path, MAX_PATH_CHARS);
  366.     if (env_path = getenv("CTEXFONTS$PATH"))
  367.                 copy_path(font_path, env_path, MAX_PATH_CHARS);
  368.     if (env_path = getenv("CTEXFORMATS$PATH"))
  369.                 copy_path(format_path, env_path, MAX_PATH_CHARS);
  370. */        
  371.     if (env_path = getenv("TEXINPUTS"))
  372.                 copy_path(input_path, env_path, MAX_PATH_CHARS);
  373.     if (env_path = getenv("TEXFONTS"))
  374.                 copy_path(font_path, env_path, MAX_PATH_CHARS);
  375.     if (env_path = getenv("TEXFORMATS"))
  376.                 copy_path(format_path, env_path, MAX_PATH_CHARS);
  377. }
  378.  
  379. /*
  380.  * copy_path(s1,s2,n) copies at most n characters (including the null)
  381.  * from string s2 to string s1, giving an error message for paths
  382.  * that are too long.
  383.  */
  384.  
  385. copy_path (s1, s2, n)
  386.         char*           s1;
  387.         char*           s2;
  388.         int                     n;
  389. {
  390.         int                     i;
  391.  
  392.         i = 0;
  393.     while (s2[i] != NUL) {
  394.                 s1[i] = s2[i];
  395.                 incr(i);
  396.                 if (i == n) {
  397.                         fprintf(stderr, "! Environment search path is too big\n");
  398.                         s1[i - 1] = '\0';
  399.                         return;
  400.                 }
  401.         }
  402.         s1[i] = NUL;
  403. }
  404.  
  405. #define append_to_def_area(C) \
  406.         {if (i == MAX_PATH_CHARS)  \
  407.                 overflow("def_area", MAX_PATH_CHARS); \
  408.         def_area[i] = C; \
  409.         incr(i), incr(j);}
  410.  
  411. set_def_area()
  412. {       
  413.         char    c;
  414.         int             i;
  415.         int             j;
  416.     char        def_area[MAX_PATH_CHARS];
  417.  
  418.         i = 0;
  419.         j = str_start[job_area];
  420.         while (j < str_start[job_area + 1])
  421.                 append_to_def_area(str_pool[j]);
  422.         append_to_def_area(','); /*ACORN*/
  423.         j = 0;
  424.         while ((c = input_path[j]) != NUL)
  425.                 append_to_def_area(c);
  426.         append_to_def_area(NUL);
  427.         strcpy(input_path, def_area);
  428. }
  429.  
  430. /*
  431.  *      test_access(amode, file_path)
  432.  *
  433.  *  Test whether or not the file whose name is in the global name_of_file
  434.  *  can be opened for reading according to access mode.
  435.  *
  436.  *  If the filename given in name_of_file does not begin with '/', we try 
  437.  *  prepending all the ':'-separated areanames in the appropriate path to the
  438.  *  filename until access can be made.
  439.  */
  440.  
  441. bool
  442. test_access (amode, file_path)
  443.         int             amode;
  444.         int             file_path;
  445. {
  446.     int         nl;
  447.     bool        ok;
  448.     char        original_name[FILE_NAME_SIZE];
  449.  
  450.         strcpy(original_name, name_of_file);
  451.     nl = name_length;
  452.     switch (file_path)
  453.         {
  454.         case NO_FILE_PATH:
  455.             cur_path = NULL;
  456.             break;
  457.  
  458.         case INPUT_FILE_PATH: 
  459.             cur_path = input_path;
  460.             break;
  461.  
  462.         case FONT_FILE_PATH: 
  463.             cur_path = font_path;
  464.             break;
  465.  
  466.         case FORMAT_FILE_PATH:
  467.             cur_path = format_path;
  468.             break;
  469.     }
  470.     if (name_of_file[0] == '/' ||
  471.                 name_of_file[0] == '.' && name_of_file[1] == '/')
  472.                 cur_path = NULL;
  473.     do {
  474.                 strcpy(name_of_file, original_name);
  475.         name_length = nl;
  476.                 get_real_name();
  477.                 switch (amode)
  478.                 {
  479.                 case READ_ACCESS:
  480.                         ok = access(name_of_file, amode) == 0 ? TRUE : FALSE;
  481.                         break;
  482.  
  483.                 case WRITE_ACCESS:
  484.                         {FILE *fp = fopen(name_of_file, "w");
  485.                         ok = fp != (FILE *) 0;
  486.                         if (ok) fclose(fp);}
  487.                         break;
  488.                 }
  489.     } while (!ok && cur_path != NULL);
  490.     return ok;
  491. }
  492.  
  493. #define append_to_real_name(C) \
  494.         {if (i == FILE_NAME_SIZE) \
  495.                 overflow("real_name", FILE_NAME_SIZE); \
  496.         real_name[i] = C; \
  497.         incr(i), incr(j);}
  498.  
  499. get_real_name ()
  500. {
  501.     int         i;
  502.         int             j;
  503.         char    real_name[FILE_NAME_SIZE];
  504.     
  505.         i = j = 0;
  506.     if (cur_path) {
  507.                 while (cur_path[j] != ',' && cur_path[j] != NUL) /*ACORN*/
  508.                         append_to_real_name(cur_path[j]);
  509. /*ACORN         if (real_name[i - 1] != '/')*/
  510. /*ACORN                 append_to_real_name('/');*/
  511.                 if (cur_path[j] == NUL)
  512.                         cur_path = NULL;
  513.                 else cur_path += j;
  514.     }
  515.         j = 0;
  516.         while (j < name_length)
  517.                 append_to_real_name(name_of_file[j]);
  518.         append_to_real_name(NUL);
  519.         strcpy(name_of_file, real_name);
  520.         name_length = i - 1;
  521. }
  522.  
  523. init_file ()
  524. {
  525.         int             i;
  526.  
  527.         name_in_progress = FALSE;
  528.         str_tex = make_string_given(".tex");
  529.         str_dvi = make_string_given(".dvi");
  530.         str_log = make_string_given(".log");
  531.         str_tfm = make_string_given(".tfm");
  532.         str_fmt = make_string_given(".fmt");
  533.         str_texput = make_string_given("texput");
  534.         for (i = 0; i <= 16; incr(i)) 
  535.                 read_open[i] = CLOSED;
  536. }
  537.